module top (
    input wire clk, 
    input wire rst,
    input wire rx, 
    output wire tx,
	 output wire [3:0] SpyOpc,//*****this is the monitor output*********
	 output wire [7:0] SpyUxData,	//*****this is the monitor output*********
	 output wire [7:0] SpyFiData,	//*****this is the monitor output*********
	 output wire [3:0] SpyChrData,
	 output reg[2:0]  TopTestLed,
	 output wire ConvTestFlag,
	 output wire CoderTestFlag,
	 output wire [3:0] counter,
	 output wire [16:0] test
);



wire rstd;
reg [7:0] tx_byte_d;
wire [7:0] rx_byte_d;
reg transmit_d;
wire received_d;
wire is_receiving_d; // Low when receive line is idle.
wire is_transmitting_d; // Low when transmit line is idle.
wire recv_error_d; // Indicates error in receiving packet. 
reg uartFifoReq;

reg try_to_send = 0;
reg toSend		 =0;
reg ReadFlag	 =1;
reg stupidCnt	 =1;




//unfunctioned output of fsm
wire [2:0] fsmChrEn;
wire [7:0] fsmChrData;
wire 	     fsmAluReq;
wire [1:0] fsmAluOp;
wire 	     fsmStackClear;

//wire the output of chr
wire 			chrStackPush;
wire 			chrStackClear;
wire 			chrCoderEn;
wire 	[16:0]chrAllData;


//wire the ouput of coder
wire 			coderConvEn;
wire 	[16:0]	coderConvData;


//wire the output of convector
wire 			convFifoWrite;
wire  [7:0] convFifoData;

//wire the output of Fifo
wire 			FifoUartEmp;
wire			FifoUartFull;
wire 	[7:0]	FifoUartData;


//wire the output of ALU
wire 			aluChrEn;
wire 	[16:0] aluChrData;
wire 			aluStackPop;


//wire the output of STACK
wire   [16:0] stackAluData;







assign test = aluChrData;






always @(posedge clk) begin
	if(rstd) begin
		tx_byte_d = 8'h00;
		transmit_d = 0;
		try_to_send <= 0;
		TopTestLed =0;
	end else if(received_d) begin
		//tx_byte_d <= rx_byte_d;		
		try_to_send <= 1;
	end
	
/*if(!is_transmitting_d && try_to_send) begin
//	if(!is_transmitting_d && try_to_send&&!FifoUartEmp) begin
		transmit_d <= 1;	
		try_to_send <= 0;
		TopTestLed <=TopTestLed+1;
	end else begin
		transmit_d <= 0;
	end*/
	if(!FifoUartEmp&&ReadFlag&&!toSend)begin
			uartFifoReq =1;
			tx_byte_d 	= FifoUartData;
			TopTestLed =TopTestLed+1;
			toSend		=1;
		end else begin
		uartFifoReq = 0;
		transmit_d = 0;	
		end
	if(!is_transmitting_d && toSend)begin
		ReadFlag=0;
		transmit_d =1;
		toSend = 0;
		end else
		ReadFlag=1;

end 
   
swdebounce sw1(.clk(clk), .X(rst), .Z(rstd));
//this is can also applied to the flag signal
//assign rstd=clk;
uart myUart(.clk(clk), 
             .rst(rstd), 
             .rx(rx), 
             .tx(tx), 
             .transmit(transmit_d), 
             .tx_byte(tx_byte_d), 
             .received(received_d), 
             .rx_byte(rx_byte_d), 
             .is_receiving(is_receiving_d), 
             .is_transmitting(is_transmitting_d), 
             .recv_error(recv_error_d));


FSM fsm(.sysclk(clk),
	.reset(rstd),
	.uartFsmReady(received_d),
	.uartFsmData(rx_byte_d),
	
	.fsmChrEn(fsmChrEn),
	.fsmChrData(fsmChrData),
	.fsmAluReq(fsmAluReq),
	.fsmAluOpcode(fsmAluOp),
	.fsmStackClear(fsmStackClear),
	.SpyOpc(SpyOpc));
	
	ALU alu(
		.systemclock(clk),
		.fsmAluReq(fsmAluReq),
		.fsmAluOpt(fsmAluOpt),
		.chrAluData(chrAluData),
		.stackAluData(stackAluData),
		
		.aluStackPop(aluStackPop),
		.aluChrEn(aluChrEn),
		.aluChrData(aluChrData)
		);
	STACK stack(
		.aluStackPop(aluStackPop),
		.chrStackPush(chrStackPush),
		.fsmStackClear(fsmStackClear),
		.reset(rstd),
		.chrStackData(chrStackData),
		
		.stackAluData(stackAluData)
		);
	
CHR chr(.sysclk(clk),
			.reset(rstd),
			.fsmChrEn(fsmChrEn),
			.fsmChrData(fsmChrData),
			.aluChrEn(aluChrEn),
			.aluChrData(aluChrData),
			
         .chrStackPush(aluChrPush),
			.chrCoderEn(chrCoderEn),
			.chrAllData(chrAllData),
			.SpyChrData(SpyChrData));
			
CODER16 coder(
		.systemclock(clk),
		.reset(rstd),
		.chrCoderEn(chrCoderEn),
		.chrCoderData(chrAllData),

		.coderConvEn(coderConvEn),
		.coderConvData(coderConvData),
		.CoderTestFlag(CoderTestFlag)
		);
		
Convector conv(
		.systemclock(clk),
		.reset(rstd),
		.coderConvEn(coderConvEn),
		.coderConvData(coderConvData),
		
		.convFifoWrite(convFifoWrite),
		.convFifoData(convFifoData),
		.ConvTestFlag(ConvTestFlag)
		);

FIFO fifo(
		.sysclk(clk),
		.reset(rstd),
		.coderFifoWrite(convFifoWrite),
		.coderFifoData(convFifoData),
		.uartFifoReq(uartFifoReq),
            
		.FifoUartEmp(FifoUartEmp),
		.FifoUartFull(FifoUartFull),
		.FifoUartData(FifoUartData),
		.counter(counter)
		);
		
		
		assign SpyUxData=tx_byte_d; //this the test leds**********************
		assign SpyFiData = convFifoData;
		            
endmodule